#! /usr/bin/env python
# -*- coding: utf-8 -*-
import ssl
import re
import json
from sys import argv
from urllib import request
from openpyxl import load_workbook, Workbook
from AppCode import appCode


class FilterOrder:
    """快递单号过滤工具类"""
    def filter(self, str):
        string = re.sub(r'\W*', '', str)
        return string


class LoadFile:
    """加载xlsx文件内容到内存工具类"""
    def __init__(self, filename):
        self.filename = filename

    def loadfile(self):
        # 打开 xlsx
        wb = load_workbook(self.filename)

        # 操作第一张表
        ws = wb.worksheets[0]

        # 获得最大的行数, 与列数
        max_row = ws.max_row
        max_column = ws.max_column

        # 实例化订单过滤工具类
        filterOrder = FilterOrder()
        # 将xlsx文件读到内存
        lists = []
        for row in ws.iter_rows(min_row=1, max_col=max_column, max_row=max_row):
            tmp = []
            i = 1
            for cell in row:
                if i == 1 and cell.value is None:
                    break
                elif i == 1:
                    tmp.append(filterOrder.filter(str(cell.value)))
                else:
                    tmp.append(cell.value)
                i += 1
            if tmp:
                lists.append(tmp)
        return lists


class ExpressInfo:
    """查询物流信息工具类"""
    def __init__(self):
        self.__host = 'https://api09.aliyun.venuscn.com'
        self.__path = '/express/trace/query'
        self.__method = 'GET'
        self.__appcode = appCode

    def run(self, number, comid=''):
        """
        查询快递信息
        :param number: str 订单号
        :param comid: str 快递公司代码
        :return: str 订单物流信息
        """
        query = 'comid={}&number={}'.format(comid, number)
        url = self.__host + self.__path + '?' + query
        header = {'Authorization': 'APPCODE ' + self.__appcode}
        ctx = ssl.create_default_context()
        ctx.check_hostname = False
        ctx.verify_mode = ssl.CERT_NONE
        requests = request.Request(url, headers=header)
        reponse = request.urlopen(requests, context=ctx).read().decode('utf-8')
        return reponse


class Prompt:
    """温馨提示、说明需要查询的条数，或者自定义查询条数"""

    def PromptInfo(self, number):
        info = '''温馨提示：
        需要查询的条数为: {}
        1.查询全部
        2.自定义查询数'''.format(number)
        print(info)
        num = number
        while True:
            inpt = input('请输入选项数字: ')
            if inpt.isdigit():
                if inpt == '1':
                    break
                elif inpt == '2':
                    num = input('请输入自定义的查询条数: ')

                    while True:
                        if num.isdigit():
                            if int(num) > number:
                                print('[error --- 数目不能大于总算]')
                                num = input('请输入自定义的查询条数: ')
                                continue
                            else:
                                break
                        else:
                            print('[error --- 请输入数字]')
                            num = input('请输入自定义的查询条数: ')
                    break
            else:
                print('[error --- 请输入数字]')
                continue
        return num


class CreateFile:
    """将结果生成xlsx文件类"""

    def HandleData(self, custom_row, data):
        # 生成已查询的xlsx文件
        wb = Workbook()
        ws = wb.active
        for row in range(0, int(custom_row)):
            ws.append(data[row])
        wb.save('{}Handle.xlsx'.format(argv[1]))

    def UntreatedData(self, max_row, custom_row, data):
        # 生成未查询的xlsx文件
        if max_row != custom_row:
            wb = Workbook()
            ws = wb.active
            for row in range(int(custom_row), int(max_row)):
                ws.append(data[row])
            wb.save('{}Untreated.xlsx'.format(argv[1]))


if __name__ == '__main__':
    # 载入文件
    file = LoadFile(argv[1])
    # 读取数据到内存
    files = file.loadfile()
    # 计算总数
    filenum = len(files)
    # 实例化提示类
    prompt = Prompt()
    # 定义查询的条数
    promptnum = prompt.PromptInfo(filenum)
    # 实例化物流查询类
    express = ExpressInfo()
    # 物流查询
    for i in range(0, int(promptnum)):
        ersInfo = []
        strs = express.run(files[i][0])
        # 总物流信息
        files[i].append(strs)
        ersInfo.append(json.loads(strs))
        # 发货物流信息
        if ersInfo and ersInfo[0]['data']['traces']:
            files[i].append(ersInfo[0]['data']['traces'][0]['time'])
            files[i].append(ersInfo[0]['data']['traces'][0]['desc'])
            # 收货物流信息
            files[i].append(ersInfo[0]['data']['traces'][-1]['time'])
            files[i].append(ersInfo[0]['data']['traces'][-1]['desc'])
    # 生成文件保存
    createFile = CreateFile()
    createFile.HandleData(promptnum, files)
    createFile.UntreatedData(filenum, promptnum, files)
